﻿namespace HashProviders
{
	/// <summary>
	/// Base interface that must be implemented by all hash providers.
	/// </summary>
	public interface IHashProvider
	{
        
        /// <summary>
		/// Compute the hash of the input byte array and return the hashed value as a byte array.
		/// </summary>
		/// <param name="inputData">Input data</param>
		/// <returns>Hashed data.</returns>
		byte[] ComputeHash(byte[] inputData);
	}
}

namespace HashProviders
{
	/// <summary>
	/// Hash provider based on SHA256
	/// </summary>
	public sealed class SHA256 : IHashProvider
	{
        /// <summary>
        /// Default constructor.
        /// </summary>
        public SHA256() { }
        
        /// <summary>
		/// Compute the hash of the input byte array and return the hashed value as a byte array.
		/// </summary>
		/// <param name="inputData">Input data</param>
		/// <returns>SHA256 Hashed data</returns>
		byte[] IHashProvider.ComputeHash(byte[] inputData)
		{
			System.Security.Cryptography.SHA256Managed x = new System.Security.Cryptography.SHA256Managed();
			return x.ComputeHash(inputData);
		}
	}

	/// <summary>
	/// Hash provider based on HMACSHA256 to allow inclusion of a hash seed value
	/// </summary>
	public sealed class HMACSHA256 : IHashProvider
	{
		private byte[] m_Key;

		/// <summary>
		/// Constructor accepting a private key (seed) value
		/// </summary>
		/// <param name="privateKey">Byte array containing the private hash seed</param>
		public HMACSHA256(byte[] privateKey)
		{
			m_Key = privateKey;
		}

		/// <summary>
		/// Compute the hash of the input byte array and return the hashed value as a byte array.
		/// </summary>
		/// <param name="inputData">Input data</param>
		/// <returns>HMACSHA256 Hashed data.</returns>
		byte[] IHashProvider.ComputeHash(byte[] inputData)
		{
			System.Security.Cryptography.HMACSHA256 x;

			if (m_Key == null)
				x = new System.Security.Cryptography.HMACSHA256();
			else
				x = new System.Security.Cryptography.HMACSHA256(m_Key);

			return x.ComputeHash(inputData);
		}
	}
	
	/// <summary>
	/// Hash provider based on SHA1
	/// </summary>
	public sealed class SHA1 : IHashProvider
	{
        /// <summary>
        /// Default constructor.
        /// </summary>
        public SHA1() { }
        
        /// <summary>
		/// Compute the hash of the input byte array and return the hashed value as a byte array.
		/// </summary>
		/// <param name="inputData">Input data</param>
		/// <returns>SHA1 Hashed data.</returns>
		byte[] IHashProvider.ComputeHash(byte[] inputData)
		{
			System.Security.Cryptography.SHA1Managed x = new System.Security.Cryptography.SHA1Managed();
			return x.ComputeHash(inputData);
		}
	}

	/// <summary>
	/// Hash provider based on HMACSHA1 to allow inclusion of a hash seed value
	/// </summary>
	public sealed class HMACSHA1 : IHashProvider
	{
		private byte[] m_Key;

		/// <summary>
		/// Constructor accepting a private key (seed) value
		/// </summary>
		/// <param name="privateKey">Byte array containing the private hash seed</param>
		public HMACSHA1(byte[] privateKey)
		{
			m_Key = privateKey;
		}

		/// <summary>
		/// Compute the hash of the input byte array and return the hashed value as a byte array.
		/// </summary>
		/// <param name="inputData">Input data</param>
		/// <returns>HMACSHA1 Hashed data.</returns>
		byte[] IHashProvider.ComputeHash(byte[] inputData)
		{
			System.Security.Cryptography.HMACSHA1 x;

			if (m_Key == null)
				x = new System.Security.Cryptography.HMACSHA1();
			else
				x = new System.Security.Cryptography.HMACSHA1(m_Key);

			return x.ComputeHash(inputData);
		}
	}
}